package com.echat.serviceapigateway.zuul.filter;

import com.echat.commonlib.exception.exc.EchatSecurityException;
import com.echat.serviceapigateway.security.interceptor.AuthorizedInterceptor;
import com.echat.serviceapigateway.security.service.UserService;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * Created by chenmohan on 2018/08/30
 *
 * @description
 */
@Component
@Log4j2
public class AcessFilter extends ZuulFilter {

    private static final String requestQueryParams = "requestQueryParams";

    @Autowired
    AuthorizedInterceptor authorizedInterceptor;

    @Autowired
    UserService userService;
    /**
     * 如果该配置为false , 那么不authorizedInterceptor调用
     */
    @Value("${echat.service.auth.enable}")
    Boolean authEnable;

    @Override
    public String filterType() {
        return "pre";
    }

    @Override
    public int filterOrder() {
        return 0;
    }

    @Override
    public boolean shouldFilter() {
        return true;
    }

    @Override
    public Object run() {
        RequestContext currentContext = RequestContext.getCurrentContext();
        HttpServletRequest request = currentContext.getRequest();
        HttpServletResponse response = currentContext.getResponse();
        String accessKey = request.getParameter("accessKey");
        String userId = userService.getUserIdByAccessKey(accessKey);
        try {
            if (authEnable) {
                authorizedInterceptor.preHandle(request, userId, request.getRequestURI());
            }
            //向request的paramter中添加参数 userId
            /*
            requestQueryParams.put("userId", Arrays.asList(new String[]{userId}));
            currentContext.setRequestQueryParams(requestQueryParams);
            */
            addEssentialParamters(currentContext, userId);
            //设置响应状态
            currentContext.setSendZuulResponse(true);
        } catch (EchatSecurityException e) {
            //网关接口认证、鉴权时发生的异常,这些异常是预料到的,可以catch处理的
            try {
                request.getRequestDispatcher("/errorWithJson?code=" + e.getCode() + "&msg=" + e.getMessage()).forward(request, response);
            } catch (Exception e1) {
                log.error("EchatSecurityException 请求转发出错 {}", e.getMessage());
            }
            currentContext.setSendZuulResponse(false);
        } catch (Exception e) {
            //除此以外的异常是没有预料到的,是不能处理的,写日志吧
            currentContext.setSendZuulResponse(false);
            log.error("gateway error -- " + e.getCause() + ": " + e.getMessage());
            throw e;
        }
        long t1 = System.currentTimeMillis();
        return currentContext;
    }

    /**
     * 在接口认证通过后,向Request中添加必要参数,userId ...
     */
    private void addEssentialParamters(RequestContext ctx) {
        Map<String, List<String>> requestQueryParams = ctx.getRequestQueryParams();
        //添加UserId
        String accessKey = requestQueryParams.get("accessKey").get(0);
        Long userId = userService.getUserByAccessKey(accessKey).getId();
        requestQueryParams.put("userId", Arrays.asList(new String[]{userId + ""}));
        ctx.setRequestQueryParams(requestQueryParams);
    }

    /**
     * 在接口认证通过后,向Request中添加必要参数,userId ...
     */
    private void addEssentialParamters(RequestContext ctx, String userId) {
        Map<String, List<String>> requestQueryParams = ctx.getRequestQueryParams();
        requestQueryParams.put("userId", Arrays.asList(new String[]{userId}));
        ctx.setRequestQueryParams(requestQueryParams);
    }
    /*
    private String getUserId(RequestContext ctx) {
        Map<String, List<String>> requestQueryParams = ctx.getRequestQueryParams();
        String accessKey = requestQueryParams.get("accessKey").get(0);
        return userService.getUserIdByAccessKey(accessKey);

    }

    /**
     * 在接口认证通过后,向Request中添加必要参数,userId ...
     */
    /*
    private void addEssentialParamters(RequestContext ctx, Map<String, String> parameters) {
        Map<String, List<String>> requestQueryParams = ctx.getRequestQueryParams();
        //添加UserId
        for (Map.Entry<String, String> e : parameters.entrySet()) {
            requestQueryParams.put(e.getKey(), Arrays.asList(new String[]{e.getValue()}));
        }
        ctx.setRequestQueryParams(requestQueryParams);
    }
    */
}
